import fs from 'fs-extra';
import path from 'path';
import { BaseTask, TaskResult } from "../../common/tasks/BastTask.js";
import { incVersionCode } from '../../CommonAction.js';
import { layatoolchain, ILayaBuildConfig } from '../../layatoolchain.js';
import { toolchain } from '../../toolchain.js';

export class LayaPreBuildTask extends BaseTask<void> {
    async run(): Promise<TaskResult<void>> {
        const pfs = this.cmdOption.gameIds.split(/,\s*/);

        // 检查创建原始发布记录
        const md5Root = layatoolchain.projPublishRecRoot(this.cmdOption.oldToolsRoot);
        console.log('md5Root:', md5Root);
        if (!fs.existsSync(md5Root)) {
            console.log('md5 record root not exists, try init:', md5Root);
            await fs.mkdir(md5Root);
            await toolchain.svnClient.add(md5Root);
            await toolchain.svnClient.commit('auto init project md5', md5Root);
        } else {
            await toolchain.svnClient.cleanup(false, md5Root);
            await toolchain.svnClient.revert(md5Root);
            await toolchain.svnClient.update(md5Root);
        }
        for (const pf of pfs) {
            const md5FolderPath = path.join(md5Root, pf);
            console.log('md5FolderPath:', md5FolderPath);
            if (!fs.existsSync(md5FolderPath)) {
                console.log('pf md5 record not exist, try init:', md5FolderPath);
                await fs.copy(layatoolchain.newRecRoot(this.cmdOption.oldToolsRoot), md5FolderPath);
                await toolchain.svnClient.add(md5FolderPath);
                await toolchain.svnClient.commit('auto init project md5', md5FolderPath);
            } else {
                await toolchain.svnClient.cleanup(false, md5FolderPath);
                await toolchain.svnClient.revert(md5FolderPath);
                await toolchain.svnClient.update(md5FolderPath);
            }
        }

        // 读入PlatConst.ts
        const platConst = await this.readPropertiesFromTs(path.join(toolchain.params.workSpacePath, 'src/plat/PlatConst.ts'));
        // 读入BuildConfig.ts
        for (const pf of pfs) {
            // increase版本号
            const versionCode = await incVersionCode(path.join(layatoolchain.pfPublishRecRoot(this.cmdOption.oldToolsRoot, pf), 'version.txt'));

            const buildConfig = await this.readPropertiesFromTs(path.join(layatoolchain.projectFilesRoot(pf, toolchain.params.projectType), 'BuildConfig.ts')) as ILayaBuildConfig;
            let pfValue = buildConfig['pf'] as string;
            if (pfValue.startsWith('PlatConst.')) {
                pfValue = platConst[pfValue.substring(10)];
                buildConfig['pf'] = pfValue;
            }
            buildConfig['version'] = `1.0.${versionCode}`;
            layatoolchain.vars.buildConfigMap[pf] = buildConfig;
            console.log(`BuildConfig - ${pf}:`, buildConfig);
        }

        console.log('[注意] projectfiles里的文件覆盖拷贝已废弃，请考虑通过其他方式实现');

        return { success: true, errorCode: 0, data: void 0 };
    }

    private async readPropertiesFromTs(file: string): Promise<{ [prop: string]: any }> {
        const platConstContent = await fs.readFile(file, 'utf-8');
        const properties = platConstContent.matchAll(/public (?:static )?(\w+)(?::\s?(\S+))?\s?=\s?(.+);/g);
        const propObj: { [prop: string]: any } = {};
        for (const prop of properties) {
            const varName = prop[1];
            const varType = prop[2];
            let varValue: any = prop[3];
            if (varType == 'string' && (varValue[0] == '"' || varValue[0] == "'"))
                varValue = varValue.substring(1, varValue.length - 1);
            else if (varType == 'number')
                varValue = Number(varValue);
            else if (varValue.startsWith('[') && varValue.endsWith(']') || varValue.startsWith('{') && varValue.endsWith('}'))
                varValue = JSON.parse(varValue);
            
            propObj[varName] = varValue
        }
        return propObj;
    }
}
